home *** CD-ROM | disk | FTP | other *** search
- s noted in the README file, the current version of the array class
- oes not have a copy-constructor, although the first version had one.
- he first version was clearly wrong, and I thank Tom Cargill for
- ointing this out.
-
- have not been able to make the copy-constructor work properly with
- y compiler (AT&T 3.0.1), although I know what I would like to do. If
- ou can find a useful work-around, or have a compiler that may handle
- he approach described below, please let me know. As always, I will
- ppreciate your comments.
-
- he code examples below are based on the declaration of Array<T>, see
- rray.H for details.
-
-
- orrect behaviour of copy-constructor.
-
- my view, the only correct behaviour for the array copy-constructor
- s to create copies of each element with the copy-constructor of the
- lement type. In particular, I think the following implementation is
- rong:
-
- emplate <class T>
- rray<T>::Array(const Array<T>& a)
- : low(a.low), sz(a.sz)
-
- data = new T[sz];
- assert(data != 0);
- for (unsigned i = 0; i < sz; i++)
- data[i] = a.data[i];
-
-
- t first creates an array, initializing every element with the default
- onstructor, and then uses the assignment operator to change the
- alues of the new array elements. Of course, this approach works well
- or simple element types, such as, ints and doubles.
-
-
- correct copy-constructor.
-
- he original version had a copy-constructor that tried very hard to
- et the initialization right, and that part was in fact correct. The
- rick is to allocate the right amount of space without doing the
- efault initialization, and then do the element-wise initialization:
-
- emplate <class T>
- rray<T>::Array(const Array<T>& a)
- : low(a.low), sz(a.sz)
-
- data = (T*) new char[sizeof(T)*sz];
- assert(data != 0);
- for (unsigned i = 0; i < sz; i++)
- new (data+i) T(a.data[i]);
-
-
- hat piece of code must then be matched by an appropriate destructor,
- hich calls the destructor for each element:
-
- emplate <class T>
- rray<T>::~Array()
-
- for (unsigned i = 0; i < sz; i++)
- data[i].T::~T();
- delete (char *) data;
-
-
- nfortunately, Cfront 3.0.1 does not seem to recognize "T::~T" in a
- emplate, and now I have run out of ideas! Maybe I just got it all
- rong, and in that case I would be terribly grateful for your advice.
-
-
- riginal error.
-
- om Cargill found a related bug in my original code: that I mixed
- vector new" and "plain new" in my class. The default constructor
- llocated a vector of Ts with
-
- new T[sz]
-
- hile the copy-constructor allocated a raw piece of memory with
-
- (T*) new char[sizeof(T)*sz]
-
- hich was then initialized. However, the destructor assumed vector
- llocation:
-
- delete [] data;
-
- hat happens is that you will run the destructors if the array was
- ade with the default constructor, but not if the array was made with
- he copy-constructor. The behaviour depends on how Cfront implements
- ew of vectors.
-
- he solution is to only allocate raw storage (also in the default
- onstructor) and use explicit construction/destruction of the
- lements.
-